package com.glink.gateway.common;

import cn.hutool.core.lang.Assert;
import com.glink.common.exception.GeneralSimpleException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * Created by IntelliJ IDEA.
 *
 * @Author : qiushaoshan
 * @create 2024/6/26 9:50
 */
public class AntiReplayValidator {

    public static AntiReplayWorker builder() {
        return new AntiReplayWorker();
    }

    public static class AntiReplayWorker {

        /**
         * 请求时间
         */
        private long timestamp;

        /**
         * 接口地址
         */
        private String url;
 
        public AntiReplayWorker timestamp(Long timestamp) {
            Assert.notNull(timestamp, "请求时间不能为空");
            this.timestamp = timestamp;
            return this;
        }

        public AntiReplayWorker url(String url) {
            this.url = url;
            return this;
        }

        public void execute() throws GeneralSimpleException {
            long currentTimeMillis = System.currentTimeMillis();
            // 判断请求时间是否过期
            if (currentTimeMillis - this.timestamp > ReplayProperties.props().getRequest().getExpireTime()) {
                throw new GeneralSimpleException("200003");
            }

            String key = genKey();
            RedisTemplate<String, String> redisTemplate = SpringContextUtil.getBean("redisTemplate", RedisTemplate.class);
            //如果requestId存在redis中直接返回
            String temp = redisTemplate.opsForValue().get(key);
            if (StringUtils.isNotBlank(temp)) {
                throw new GeneralSimpleException("200004");
            }
            redisTemplate.opsForValue().set(key, String.valueOf(this.timestamp), ReplayProperties.props().getCache().getLockHoldTime(), TimeUnit.MINUTES);
        }

        private String genKey() {
            return ReplayProperties.props().getCache().getCacheKeyPrefix()
                    + ":"
                    + this.url
                    + ":"
                    + this.timestamp;
        }

    }
}


